package thread;

/**
 * 同步块
 *
 */
public class SyncDemo2 {
    public static void main(String[] args) {
        Shop shop = new Shop();
        Shop shop1 = new Shop();
        Thread t1 = new Thread("李欢"){
            @Override
            public void run() {
                shop.buy();
            }
        };
        Thread t2 = new Thread("panda"){
            @Override
            public void run() {
//                shop.buy();
                shop1.buy();
            }

        };

        t1.start();
        t2.start();
    }
}

class Shop {
    public void buy(){
        try {
            Thread t = Thread.currentThread();
            System.out.println(t.getName() + "：正在挑衣服...");
            Thread .sleep(2500);
             /*
                同步块使用时要指定同步监视器对象，该对象的选取要同时满足:
                1:必须是一个引用类型实例
                2:多个需要同步执行该代码片段的线程看到的该对象必须是同一个

                合适的锁对象应当是存在并发安全问题时可以限制多个线程同步执行，
                不存在并发安全问题时可以同时执行。
             */


//            synchronized (this){
//            synchronized (new Object()){//上锁了，但是不是上的同一个调用对象
            synchronized ("花式咖啡"){/*
                    不是合适的锁对象，因为字符串字面量对象全局唯一，
                    这会导致多个线程执行不同的shop的buy方法时(没有并发安全问题时)
                    也要求同步执行，这会降低效率。
                 */
                System.out.println(t.getName() + "：正在试衣服...");
                Thread .sleep(2500);
                System.out.println(t.getName() + "离开试衣间。");
            }


            System.out.println(t.getName() + "结账离开。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }


}